﻿using System;
using System.Collections.Generic;
using System.Xml;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YJKRevitFamilyDataBase;
using YJKExcelFormTool.DataDefine;

namespace YJKExcelFormTool.Creator
{
	public class TableCreator
	{
		public double GetTableRowHeight(TextNoteType textNoteType)
		{
			Parameter parameter = textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE);
			if (parameter == null)
			{
				throw new Exception("当前字体文字高度属性为空!");
			}
			return parameter.AsDouble() * 2.0;
		}

		public List<MaterialProgramInfos.BasicInfo> GetProgramInfoList(string tableSettingFile, bool isExcelTemplate)
		{
			List<MaterialProgramInfos.BasicInfo> list = new List<MaterialProgramInfos.BasicInfo>();
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(tableSettingFile);
			XmlNode xmlNode = xmlDocument.SelectSingleNode("ProgramList");
			if (xmlNode == null)
			{
				return list;
			}
			foreach (object obj in xmlNode.ChildNodes)
			{
				XmlElement xmlElement = ((XmlNode)obj).SelectSingleNode("BasicInfos") as XmlElement;
				MaterialProgramInfos.BasicInfo item = default(MaterialProgramInfos.BasicInfo);
				try
				{
					TableHead._Tag_HeadType tag_HeadType = (TableHead._Tag_HeadType)Convert.ToInt32(xmlElement.GetAttribute("TemplateType"));
					if ((isExcelTemplate && tag_HeadType == TableHead._Tag_HeadType.HT_EXCEL) || (!isExcelTemplate && tag_HeadType == TableHead._Tag_HeadType.HT_FAMILY))
					{
						item.m_Name = xmlElement.GetAttribute("Name");
						item.m_Describe = xmlElement.GetAttribute("Describe");
						item.m_Id = xmlElement.GetAttribute("Id");
						list.Add(item);
					}
				}
				catch (Exception)
				{
				}
			}
			return list;
		}

		public void RemoveProgram(string tableSettingFile, string programId)
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(tableSettingFile);
			XmlNode xmlNode = xmlDocument.SelectSingleNode("ProgramList");
			foreach (object obj in xmlNode.ChildNodes)
			{
				XmlNode xmlNode2 = (XmlNode)obj;
				if ((xmlNode2.SelectSingleNode("BasicInfos") as XmlElement).GetAttribute("Id").CompareTo(programId) == 0)
				{
					xmlNode.RemoveChild(xmlNode2);
					break;
				}
			}
			try
			{
				xmlDocument.Save(tableSettingFile);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
		}

		public void WriteTableSetting(TableInfos tableInfos, string tableSettingFile)
		{
			XmlDocument xmlDocument = new XmlDocument();
			XmlNode xmlNode = xmlDocument.CreateNode(XmlNodeType.XmlDeclaration, "", "");
			XmlNode xmlNode2 = xmlNode;
			xmlNode2.InnerText += " encoding=\"GB2312\"";
			xmlDocument.AppendChild(xmlNode);
			XmlElement xmlElement = xmlDocument.CreateElement("", "SettingRoot", "");
			xmlElement.SetAttribute("version", "3.0");
			xmlDocument.AppendChild(xmlElement);
			XmlElement xmlElement2 = xmlDocument.CreateElement("Setting");
			xmlElement2.SetAttribute("HeadType", ((int)tableInfos.TableHeadType).ToString());
			xmlElement2.SetAttribute("AutoCellsSize", tableInfos.AutoCellsSize.ToString());
			xmlElement2.SetAttribute("FontSettingName", tableInfos.FontName());
			xmlElement2.SetAttribute("HMargin", tableInfos.HMargin.ToString());
			xmlElement2.SetAttribute("VMargin", tableInfos.VMargin.ToString());
			xmlElement.AppendChild(xmlElement2);
			XmlElement xmlElement3 = xmlDocument.CreateElement("HeadInfos");
			List<TableHeadCell> tableHeadInfos = tableInfos.Head.TableHeadInfos;
			xmlElement3.SetAttribute("HeadCellCount", tableHeadInfos.Count.ToString());
			TableCreator.WriteHeadCellList(xmlDocument, tableHeadInfos, ref xmlElement3);
			xmlElement.AppendChild(xmlElement3);
			XmlElement xmlElement4 = xmlDocument.CreateElement("HeadColumnsWidth");
			List<double> cellWidthList = tableInfos.Head.GetCellWidthList();
			xmlElement4.SetAttribute("Count", cellWidthList.Count.ToString());
			for (int i = 0; i < cellWidthList.Count; i++)
			{
				double num = cellWidthList[i];
				XmlElement xmlElement5 = xmlDocument.CreateElement("ColWidth" + (i + 1).ToString());
				xmlElement5.InnerText = num.ToString();
				xmlElement4.AppendChild(xmlElement5);
			}
			xmlElement.AppendChild(xmlElement4);
			XmlElement xmlElement6 = xmlDocument.CreateElement("HeadRowsHeight");
			List<double> cellHeightList = tableInfos.Head.GetCellHeightList();
			xmlElement6.SetAttribute("Count", cellHeightList.Count.ToString());
			for (int i = 0; i < cellHeightList.Count; i++)
			{
				double num2 = cellHeightList[i];
				XmlElement xmlElement7 = xmlDocument.CreateElement("RowHeight" + (i + 1).ToString());
				xmlElement7.InnerText = num2.ToString();
				xmlElement6.AppendChild(xmlElement7);
			}
			xmlElement.AppendChild(xmlElement6);
			try
			{
				xmlDocument.Save(tableSettingFile);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
		}

		public TableInfos ReadTableSetting(string tableSettingFile)
		{
			XmlDocument xmlDocument = new XmlDocument();
			try
			{
				xmlDocument.Load(tableSettingFile);
			}
			catch (Exception)
			{
				return new TableInfos();
			}
			XmlNode xmlNode = xmlDocument.SelectSingleNode("SettingRoot");
			string text = "";
			try
			{
				text = (xmlNode as XmlElement).GetAttribute("version");
			}
			catch (Exception)
			{
				return new TableInfos();
			}
			if (text.CompareTo("3.0") == 0)
			{
				XmlElement xmlElement = xmlNode.SelectSingleNode("Setting") as XmlElement;
				TableHead._Tag_HeadType tableHeadType = (TableHead._Tag_HeadType)Convert.ToInt32(xmlElement.GetAttribute("HeadType"));
				bool autoCellsSize = Convert.ToBoolean(xmlElement.GetAttribute("AutoCellsSize"));
				string attribute = xmlElement.GetAttribute("FontSettingName");
				TextNoteType textNoteType = this.GetTextNoteType(attribute);
				double hMargin = Convert.ToDouble(xmlElement.GetAttribute("HMargin"));
				double vMargin = Convert.ToDouble(xmlElement.GetAttribute("VMargin"));
				List<TableHeadCell> tableHeadInfos = new List<TableHeadCell>();
				TableCreator.ReadHeadCellList(xmlNode.SelectSingleNode("HeadInfos") as XmlElement, ref tableHeadInfos);
				XmlElement xmlElement2 = xmlNode.SelectSingleNode("HeadColumnsWidth") as XmlElement;
				List<double> list = new List<double>();
				int num = Convert.ToInt32(xmlElement2.GetAttribute("Count"));
				for (int i = 0; i < num; i++)
				{
					XmlElement xmlElement3 = xmlElement2.SelectSingleNode("ColWidth" + (i + 1).ToString()) as XmlElement;
					list.Add(Convert.ToDouble(xmlElement3.InnerText));
				}
				XmlElement xmlElement4 = xmlNode.SelectSingleNode("HeadRowsHeight") as XmlElement;
				List<double> list2 = new List<double>();
				int num2 = Convert.ToInt32(xmlElement4.GetAttribute("Count"));
				for (int i = 0; i < num2; i++)
				{
					XmlElement xmlElement5 = xmlElement4.SelectSingleNode("RowHeight" + (i + 1).ToString()) as XmlElement;
					list2.Add(Convert.ToDouble(xmlElement5.InnerText));
				}
				TableSourceInfo tableSourceInfo = new TableSourceInfo();
				return new TableInfos(new TableHead(tableHeadType, tableSourceInfo, tableHeadInfos, num2, num, list2, list), null, textNoteType, hMargin, vMargin, autoCellsSize);
			}
			return new TableInfos();
		}

		protected static void WriteHeadCellList(XmlDocument xmlDoc, List<TableHeadCell> cellList, ref XmlElement curElement)
		{
			for (int i = 0; i < cellList.Count; i++)
			{
				TableHeadCell tableHeadCell = cellList[i];
				XmlElement xmlElement = xmlDoc.CreateElement("Cell" + (i + 1).ToString());
				XmlElement newChild = null;
				TableCreator.WriteHeadCellMapping(xmlDoc, tableHeadCell, out newChild);
				xmlElement.AppendChild(newChild);
				XmlElement xmlElement2 = xmlDoc.CreateElement("ColumnNumRang");
				xmlElement2.SetAttribute("Count", tableHeadCell.ColIndex.Count.ToString());
				for (int j = 0; j < tableHeadCell.ColIndex.Count; j++)
				{
					int num = tableHeadCell.ColIndex[j];
					XmlElement xmlElement3 = xmlDoc.CreateElement("ColNum" + (j + 1).ToString());
					xmlElement3.InnerText = num.ToString();
					xmlElement2.AppendChild(xmlElement3);
				}
				xmlElement.AppendChild(xmlElement2);
				XmlElement xmlElement4 = xmlDoc.CreateElement("RowNumRang");
				xmlElement4.SetAttribute("Count", tableHeadCell.RowIndex.Count.ToString());
				for (int j = 0; j < tableHeadCell.RowIndex.Count; j++)
				{
					int num2 = tableHeadCell.RowIndex[j];
					XmlElement xmlElement5 = xmlDoc.CreateElement("RowNum" + (j + 1).ToString());
					xmlElement5.InnerText = num2.ToString();
					xmlElement4.AppendChild(xmlElement5);
				}
				xmlElement.AppendChild(xmlElement4);
				curElement.AppendChild(xmlElement);
			}
		}

		protected static void WriteHeadCellMapping(XmlDocument xmlDoc, TableHeadCell cell, out XmlElement xeMapping)
		{
			xeMapping = xmlDoc.CreateElement("Mapping");
			TableHeadCellKey key = cell.Key;
			XmlElement xmlElement = xmlDoc.CreateElement("Key");
			xmlElement.SetAttribute("keyType", key.KeyType().ToString());
			XmlElement xmlElement2 = xmlDoc.CreateElement("Name");
			xmlElement2.InnerText = key.KeyName;
			xmlElement.AppendChild(xmlElement2);
			XmlElement xmlElement3 = xmlDoc.CreateElement("CombinationOfAttributes");
			xmlElement3.SetAttribute("CmbAtrCount", key.CombinationOfAttributes.Count.ToString());
			for (int i = 0; i < key.CombinationOfAttributes.Count; i++)
			{
				string categoryName = key.CombinationOfAttributes[i].CategoryName;
				XmlElement xmlElement4 = xmlDoc.CreateElement("ComAtr" + (i + 1).ToString());
				xmlElement4.SetAttribute("CategoryName", categoryName);
				List<string> attributesName = key.CombinationOfAttributes[i].AttributesName;
				xmlElement4.SetAttribute("AttributesCount", attributesName.Count.ToString());
				for (int j = 0; j < attributesName.Count; j++)
				{
					string value = attributesName[j];
					XmlElement xmlElement5 = xmlDoc.CreateElement("Attribute" + (j + 1).ToString());
					xmlElement5.SetAttribute("AttributeName", value);
					xmlElement4.AppendChild(xmlElement5);
				}
				List<string> delimiter = key.CombinationOfAttributes[i].Delimiter;
				xmlElement4.SetAttribute("DelimitersCount", delimiter.Count.ToString());
				for (int j = 0; j < delimiter.Count; j++)
				{
					string value2 = delimiter[j];
					XmlElement xmlElement6 = xmlDoc.CreateElement("Delimiter" + (j + 1).ToString());
					xmlElement6.SetAttribute("DelimiterName", value2);
					xmlElement4.AppendChild(xmlElement6);
				}
				xmlElement3.AppendChild(xmlElement4);
			}
			xmlElement.AppendChild(xmlElement3);
			xeMapping.AppendChild(xmlElement);
			XmlElement xmlElement7 = xmlDoc.CreateElement("Value");
			xmlElement7.InnerText = cell.Value;
			xeMapping.AppendChild(xmlElement7);
		}

		protected static void ReadHeadCellList(XmlElement curElement, ref List<TableHeadCell> cellList)
		{
			int num = Convert.ToInt32(curElement.GetAttribute("HeadCellCount"));
			for (int i = 0; i < num; i++)
			{
				XmlElement xmlElement = curElement.SelectSingleNode("Cell" + (i + 1).ToString()) as XmlElement;
				TableHeadCellKey key = null;
				string value = "";
				TableCreator.ReadHeadCellMapping(xmlElement, out key, ref value);
				List<int> list = new List<int>();
				XmlElement xmlElement2 = xmlElement.SelectSingleNode("ColumnNumRang") as XmlElement;
				int num2 = Convert.ToInt32(xmlElement2.GetAttribute("Count"));
				for (int j = 0; j < num2; j++)
				{
					XmlElement xmlElement3 = xmlElement2.SelectSingleNode("ColNum" + (j + 1).ToString()) as XmlElement;
					list.Add(Convert.ToInt32(xmlElement3.InnerText));
				}
				List<int> list2 = new List<int>();
				XmlElement xmlElement4 = xmlElement.SelectSingleNode("RowNumRang") as XmlElement;
				int num3 = Convert.ToInt32(xmlElement4.GetAttribute("Count"));
				for (int j = 0; j < num3; j++)
				{
					XmlElement xmlElement5 = xmlElement4.SelectSingleNode("RowNum" + (j + 1).ToString()) as XmlElement;
					list2.Add(Convert.ToInt32(xmlElement5.InnerText));
				}
				TableHeadCell item = new TableHeadCell(list2, list, value, key, TableHeadCell.CellInfoType.CIT_Text);
				cellList.Add(item);
			}
		}

		protected static void ReadHeadCellMapping(XmlElement curElement, out TableHeadCellKey cellKey, ref string cellValue)
		{
			XmlElement xmlElement = curElement.SelectSingleNode("Mapping") as XmlElement;
			XmlElement xmlElement2 = xmlElement.SelectSingleNode("Key") as XmlElement;
			string innerText = (xmlElement2.SelectSingleNode("Name") as XmlElement).InnerText;
			List<CombinationOfAttributes> list = new List<CombinationOfAttributes>();
			XmlElement xmlElement3 = xmlElement2.SelectSingleNode("CombinationOfAttributes") as XmlElement;
			int num = Convert.ToInt32(xmlElement3.GetAttribute("CmbAtrCount"));
			for (int i = 0; i < num; i++)
			{
				XmlElement xmlElement4 = xmlElement3.SelectSingleNode("ComAtr" + (i + 1).ToString()) as XmlElement;
				string attribute = xmlElement4.GetAttribute("CategoryName");
				List<string> list2 = new List<string>();
				int num2 = Convert.ToInt32(xmlElement4.GetAttribute("AttributesCount"));
				for (int j = 0; j < num2; j++)
				{
					string attribute2 = (xmlElement4.SelectSingleNode("Attribute" + (j + 1).ToString()) as XmlElement).GetAttribute("AttributeName");
					list2.Add(attribute2);
				}
				List<string> list3 = new List<string>();
				int num3 = Convert.ToInt32(xmlElement4.GetAttribute("DelimitersCount"));
				for (int j = 0; j < num3; j++)
				{
					string attribute3 = (xmlElement4.SelectSingleNode("Delimiter" + (j + 1).ToString()) as XmlElement).GetAttribute("DelimiterName");
					list3.Add(attribute3);
				}
				CombinationOfAttributes item = new CombinationOfAttributes(attribute, list2, list3);
				list.Add(item);
			}
			cellKey = new TableHeadCellKey(innerText, list);
			XmlElement xmlElement5 = xmlElement.SelectSingleNode("Value") as XmlElement;
			cellValue = xmlElement5.InnerText;
		}

		protected TextNoteType GetTextNoteType(string textNoteType)
		{
			TextNoteType result = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Revit.Application.ActiveUIDocument.Document);
			filteredElementCollector.OfClass(typeof(TextNoteType));
			foreach (Element element in filteredElementCollector)
			{
				TextNoteType textNoteType2 = (TextNoteType)element;
				if (textNoteType2.Name.CompareTo(textNoteType) == 0)
				{
					result = textNoteType2;
					break;
				}
			}
			return result;
		}

		protected SymbolTypeHeadInfos GetSymbolTypeHeadInfos(string symbolTypeName, string strDbPath)
		{
			SymbolTypeHeadInfos symbolTypeHeadInfos = new SymbolTypeHeadInfos();
			try
			{
				FamilyLibDatabase sqliteDB = FamilyLibDatabase.GetSqliteDB(SubjectType.System, this.m_Revit.Application.Application.VersionNumber);
				foreach (DbFamily dbFamily in sqliteDB.CategoryTable[strDbPath].GetAllFamilies(false, CheckType.All))
				{
					foreach (string text in sqliteDB.TypeTable[dbFamily])
					{
						DbFamilySymbol dbFamilySymbol = sqliteDB.TypeTable[dbFamily, text];
						if (dbFamilySymbol != null && text.CompareTo(symbolTypeName) == 0)
						{
							List<string> colNames = new List<string>();
							FamilySymbol familySymbol = dbFamilySymbol.Create(this.m_Revit.Application.ActiveUIDocument.Document);
							symbolTypeHeadInfos.m_SymbolId = familySymbol.Id;
							symbolTypeHeadInfos.m_Name = familySymbol.Name;
							symbolTypeHeadInfos.m_DbPath = strDbPath;
							symbolTypeHeadInfos.m_Image = dbFamily.Image;
							symbolTypeHeadInfos.m_ColNames = colNames;
							break;
						}
					}
				}
			}
			catch (Exception)
			{
				return symbolTypeHeadInfos;
			}
			return symbolTypeHeadInfos;
		}

		public static List<SymbolTypeHeadInfos> GetHeadSymbolTypeList(ExternalCommandData cmdData, string strDbPath)
		{
			List<SymbolTypeHeadInfos> list = new List<SymbolTypeHeadInfos>();
			try
			{
				FamilyLibDatabase sqliteDB = FamilyLibDatabase.GetSqliteDB(SubjectType.System, cmdData.Application.Application.VersionNumber);
				List<DbFamily> allFamilies = sqliteDB.CategoryTable[strDbPath].GetAllFamilies(false, CheckType.All);
				foreach (DbFamily dbFamily in allFamilies)
				{
					foreach (string name in sqliteDB.TypeTable[dbFamily])
					{
						DbFamilySymbol dbFamilySymbol = sqliteDB.TypeTable[dbFamily, name];
						if (dbFamilySymbol != null)
						{
							List<string> colNames = new List<string>();
							FamilySymbol familySymbol = dbFamilySymbol.Create(cmdData.Application.ActiveUIDocument.Document);
							list.Add(new SymbolTypeHeadInfos
							{
								m_SymbolId = familySymbol.Id,
								m_Name = familySymbol.Name,
								m_DbPath = strDbPath,
								m_Image = dbFamily.Image,
								m_ColNames = colNames
							});
						}
					}
				}
				if (list.Count == 0)
				{
					if (allFamilies.Count > 0)
					{
						YJKMessageBox.Show("\"族库/系统/表头/" + strDbPath + "/\"下表头族缺少\"列名组合\"属性");
					}
					else
					{
						YJKMessageBox.Show("\"族库/系统/表头/" + strDbPath + "/\"下没有表头族");
					}
				}
			}
			catch (Exception)
			{
				return list;
			}
			return list;
		}

		protected ExternalCommandData m_Revit;
	}
}
